home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / Music / EDIT / PerfectSound / source / sed3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-23  |  20.6 KB  |  975 lines

  1. /********************************/
  2. /**   Perfect Sound (C) 1986   **/
  3. /**    Anthony J. Wood         **/
  4. /**                            **/
  5. /** FILE 3 of 4                **/
  6. /**                            **/
  7. /** This Source code may be    **/
  8. /** copied for backup only.    **/
  9. /** This Source code is for    **/
  10. /** reference only, you may    **/
  11. /** NOT modify and compile     **/
  12. /** this source except for     **/
  13. /** PERSONAL use. Permission   **/
  14. /** is given to distribute     **/
  15. /** copies of the object code  **/
  16. /** generated from compiling   **/
  17. /** Perfect Sound ONLY if the  **/
  18. /** source code is not changed **/
  19. /** in any way. Permision is   **/
  20. /** granted to use subroutines **/
  21. /** in this file within your   **/
  22. /** own programs if you notify **/
  23. /** SunRize Industries of your **/
  24. /** intent to do so and        **/
  25. /** SunRize Industries agrees  **/
  26. /** to your request.           **/
  27. /**                            **/
  28. /**  SunRize Industries        **/
  29. /**  PO Box 1453               **/
  30. /**  College Station, TX 77841 **/
  31. /**  (409) 846-1311            **/
  32. /**                            **/
  33. /********************************/
  34.  
  35. #include "exec/types.h"
  36. #include "exec/exec.h"
  37. #include "exec/execbase.h"
  38. #include "intuition/intuition.h"
  39. #include "devices/audio.h"
  40. #include "fcntl.h"
  41. #include "df0:sed1.h"
  42.  
  43.  
  44. extern struct ExecBase *SysBase;     /* for memory list searches */
  45.  
  46. /******************************/
  47. /** put @ x,y pix pos        **/
  48. /******************************/
  49.  
  50. putxy(window,x,y,string,fg,bg)
  51.  
  52. struct Window *window;
  53. int x,y,fg,bg;
  54. char *string;
  55.  
  56. {
  57.  
  58. struct IntuiText text;
  59.  
  60. text.FrontPen=fg;
  61. text.BackPen=bg;
  62. text.DrawMode=JAM2;
  63. text.LeftEdge=x;
  64. text.TopEdge=y;
  65. text.ITextFont=NULL;
  66. text.IText=string;
  67. text.NextText=NULL;
  68.  
  69.  
  70. PrintIText (window->RPort,&text,0,0);
  71.  
  72. }
  73.  
  74.  
  75. drawline(Window,fx,fy,tx,ty,pen)
  76.  
  77. struct Window *Window;
  78. int fx,fy,tx,ty;
  79. int pen;
  80. {
  81. Move(Window->RPort,fx,fy);
  82. SetAPen(Window->RPort,pen);
  83. Draw(Window->RPort,tx,ty);
  84. }
  85.  
  86. /*******************/
  87. /* find a new slot */
  88. /*******************/
  89.  
  90. getslot(Window,samp)
  91.  
  92. struct Window *Window;
  93. struct Samp *samp;
  94.  
  95. {
  96. int i=0;
  97.  
  98. while(samp->lmem[i]!=0 && i<MAX_SAMPLES) i++;
  99. if (i==MAX_SAMPLES) {
  100.    msg(Window,"No slots available... Delete a sample.");
  101.    return(-1);
  102.    }
  103. return(i);
  104. }
  105.  
  106. /***********************/
  107. /** plot sample       **/
  108. /***********************/
  109.  
  110. graph(Window,samp,cur)
  111.  
  112. struct Window *Window;
  113. struct Samp *samp;
  114. int cur;
  115.  
  116. {
  117. float x,s,stp,addx;
  118. int y,val;
  119.  
  120. if (samp->lmem[cur]==0) return (0);
  121. if (samp->sm[cur]>=samp->em[cur]) return(0);
  122.  
  123. /* 1st clear screen memory in this area */
  124. SetAPen(Window->RPort,BLACK);
  125. SetBPen(Window->RPort,BLACK);
  126. RectFill(Window->RPort,2,GBOTY-255/SCALE,637,GBOTY);
  127. drawline(Window,2,GBOTY-255/SCALE-1,637,GBOTY-255/SCALE-1,WHITE);
  128. drawline(Window,2,GBOTY-255/SCALE-2,637,GBOTY-255/SCALE-2,WHITE);
  129.  
  130. stp=(float)(samp->em[cur]-samp->sm[cur])/(float)530;
  131. addx=1;
  132. if (stp<1) {
  133.    addx=1/stp;
  134.    stp=1;
  135.    }
  136. x=50;    /* line up with prop gadgets */
  137. y=GBOTY-((int)(*(samp->lmem[cur]+samp->sm[cur]))+128)/SCALE;
  138. Move(Window->RPort,(int)x,y);
  139. SetAPen(Window->RPort,WHITE);
  140.  
  141. x=x+addx;
  142. for (s=(float)samp->sm[cur]+stp;s<(float)samp->em[cur];s=s+stp) {
  143.    val=128+*(samp->lmem[cur]+(int)s);
  144.    val=GBOTY-val/SCALE;
  145.    x=x+addx;
  146.    Draw(Window->RPort,(int)x,val);
  147.    }
  148. }
  149.  
  150.  
  151. /******************/
  152. /** power (**)   **/
  153. /******************/
  154.  
  155. powr(x,y)
  156. register int x,y;
  157. {
  158. register int i,z;
  159. if (y==0) return (1);
  160. z=1;
  161. for (i=0;i<y;i++)
  162.    z=z*x;
  163. return (z);
  164. }
  165.  
  166.  
  167. /**************************************/
  168. /**   show input levels             **/
  169. /*************************************/
  170.  
  171. level(Window)
  172. struct Window *Window;
  173. {
  174. static int k,right,left,rmin,rmax,lmin,lmax,i;
  175. UBYTE *data,*direction,*pa;
  176. UBYTE *data2,*direction2;
  177. char line[80];
  178.  
  179. direction=(UBYTE *)0xBFE301;     /* set bits here to a 1 for output */
  180. data=(UBYTE *)0xBFE101;
  181. data2=(UBYTE *)0xBFD000;
  182. direction2=(UBYTE *)0xBFD200;
  183.  
  184. pa=(UBYTE *)0xBFE001;
  185. *direction=(UBYTE)0;           /* all bits are read */
  186. *data=(UBYTE)0;
  187. *direction2=(UBYTE)2+4;      /* pa1 & pa2 write */
  188. *data2=(UBYTE)2;            /* pa2 -- select right channel */
  189.  
  190. while (1==1) {
  191.    lmax=0;
  192.    rmax=0;
  193.    lmin=999;
  194.    rmin=999;
  195.    for (k=0;k<30;k++) {
  196.       if ((*pa&64)!=64) {
  197.          msg(Window,"");
  198.          return(0);
  199.          }
  200.       *data2=(UBYTE)0;           /* select both channels */
  201.       i=*data;                   /* start conversion    */
  202.       *data2=(UBYTE)RIGHT;       /* select right chennel */
  203.       for(i=0;i<5000;i++) ;      /* wait till finished */
  204.       right=*data;               /* get right channel value */
  205.       *data2=(UBYTE)LEFT;        /* select left channel */
  206.       left=*data;                /* get left channel value */
  207.       if (left<lmin) lmin=left;
  208.       if (left>lmax) lmax=left;
  209.       if (right<rmin) rmin=right;
  210.       if (right>rmax) rmax=right;
  211.       sprintf(line,"L: %3.3d %3.3d %3.3d  R: %3.3d %3.3d %3.3d   D: %4.4d",
  212.               lmin,lmax,left,rmin,rmax,right,right-left);
  213.       msg(Window,line);
  214.       }
  215.    }
  216. }
  217.  
  218. /**********************************/
  219. /** find largest memory fragment  */
  220. /**********************************/
  221.  
  222. frags()
  223.  
  224. {
  225. int    newmax=0;
  226. struct MemChunk *chunk;
  227. struct MemHeader *mem;
  228. struct ExecBase *eb = SysBase;
  229.  
  230.  
  231. Forbid();
  232. for (mem = (struct MemHeader *) eb -> MemList.lh_Head;
  233. mem -> mh_Node.ln_Succ; mem = mem -> mh_Node.ln_Succ) {
  234.    for (chunk = mem -> mh_First; chunk; chunk = chunk -> mc_Next) {
  235.    if (chunk->mc_Bytes>newmax) newmax=chunk->mc_Bytes;
  236.    }
  237. }
  238. Permit();
  239. if (newmax<40000) newmax=40000;
  240. return (newmax-40000);    /* leave some memory to prevent crashes */
  241. }
  242.  
  243.  
  244. /******************************/
  245. /*** set up gadget structures */
  246. /******************************/
  247.  
  248. makegadget()
  249.  
  250. {
  251. static struct Gadget gadget_s,gadget_e,gadget_p;
  252. static struct Gadget gw,gr;
  253. static struct PropInfo prop_s,prop_e,prop_p;
  254. static struct Image image_s,image_e,image_p;
  255. static struct IntuiText t[2];
  256. static struct Border b;
  257. int i;
  258.  
  259. static SHORT bd[]={0,0,
  260.              90,0,
  261.              90,12,
  262.              0,12,
  263.              0,0};
  264.  
  265.  
  266. /* define a propertional gadget to use for curers */
  267.  
  268. gadget_s.NextGadget=NULL;
  269. gadget_s.LeftEdge=50;
  270. gadget_s.TopEdge=GSP;
  271. gadget_s.Width=-90;
  272. gadget_s.Height=10;
  273. gadget_s.Flags=GADGHNONE|GRELWIDTH;
  274. gadget_s.Activation=FOLLOWMOUSE|GADGIMMEDIATE;
  275. gadget_s.GadgetType=PROPGADGET;
  276. gadget_s.GadgetRender=(APTR)&image_s;
  277. gadget_s.SelectRender=NULL;
  278. gadget_s.GadgetText=NULL;
  279. gadget_s.MutualExclude=NULL;
  280. gadget_s.SpecialInfo=(APTR)&prop_s;
  281. prop_s.Flags=FREEHORIZ|AUTOKNOB;
  282. prop_s.HorizPot=0;
  283. prop_s.HorizBody=0;
  284. prop_s.VertBody=MAXBODY;
  285.  
  286. movmem(&gadget_s,&gadget_e,sizeof(struct Gadget));
  287. movmem(&prop_s,&prop_e,sizeof(struct PropInfo));
  288.  
  289. movmem(&gadget_s,&gadget_p,sizeof(struct Gadget));
  290. movmem(&prop_s,&prop_p,sizeof(struct PropInfo));
  291.  
  292. gadget_e.TopEdge=GEP;
  293. gadget_e.GadgetRender=(APTR)&image_e;
  294. gadget_e.SpecialInfo=(APTR)&prop_e;
  295. gadget_s.NextGadget=&gadget_e;
  296. gadget_e.NextGadget=&gadget_p;
  297. gadget_p.NextGadget=&gw;
  298. gadget_p.TopEdge=GPP;
  299. gadget_p.GadgetRender=(APTR)&image_p;
  300. gadget_p.SpecialInfo=(APTR)&prop_p;
  301.  
  302. gw.NextGadget=&gr;
  303. gw.LeftEdge=EDGE_GW;
  304. gw.TopEdge=GPW;
  305. gw.Width=88;
  306. gw.Height=11;
  307. gw.Flags=GADGHCOMP;
  308. gw.Activation=RELVERIFY;
  309. gw.GadgetType=BOOLGADGET;
  310. gw.GadgetRender=&b;
  311. gw.SelectRender=NULL;
  312. gw.GadgetText=&t[0];
  313. gw.MutualExclude=NULL;
  314. gw.SpecialInfo=NULL;
  315.  
  316. movmem(&gw,&gr,sizeof(struct Gadget));
  317. gr.LeftEdge=EDGE_GR;
  318. gr.NextGadget=NULL;
  319. gr.TopEdge=GPR;
  320. gr.GadgetText=&t[1];
  321.  
  322. b.LeftEdge=-2;
  323. b.TopEdge=-2;
  324. b.FrontPen=3;
  325. b.DrawMode=JAM1;
  326. b.XY=&bd[0];
  327. b.Count=5;
  328. b.NextBorder=0;
  329.  
  330. for (i=0;i<2;i++) {
  331.    t[i].FrontPen=3;
  332.    t[i].BackPen=2;
  333.    t[i].DrawMode=JAM2;
  334.    t[i].LeftEdge=0;
  335.    t[i].TopEdge=1;
  336.    t[i].ITextFont=NULL;
  337.    t[i].IText="PLAY SAMPLE";
  338.    t[i].NextText=0;
  339.    }
  340. t[1].IText="PLAY RANGE";
  341.  
  342.  
  343. return ((int)&gadget_s);
  344. }
  345.  
  346. /**************************/
  347. /** flip a range of bytes */
  348. /**************************/
  349.  
  350. flip (addrs,len)
  351.  
  352. char *addrs;
  353. int len;
  354.  
  355. {
  356.  
  357. register char *s,*e;
  358. register char temp;
  359. register int k;
  360.  
  361. s=addrs;
  362. e=addrs+len-1;
  363. k=len/2;
  364.  
  365. while (k-->0) {
  366.    temp=*s;
  367.    *s=*e;
  368.    *e=temp;
  369.    s++;e--;
  370.    }
  371. return(0);
  372. }
  373.    
  374. /********************************************/
  375. /** insert a range from one samp to another */
  376. /********************************************/
  377.  
  378. move(Window,samp,start,end,position,from,to)
  379.  
  380. struct Window *Window;
  381. struct Samp *samp;
  382. int position,from,to,start,end;
  383.  
  384. {
  385.  
  386. char *y,*x;
  387. int len;
  388.  
  389.    if (start>=end) {
  390.       msg(Window,"Markers not set.");
  391.       return(0);
  392.       }
  393.  
  394.    if ((samp->type[to]==STEREO || samp->type[from]==STEREO)
  395.         && (samp->type[to]!=samp->type[from])) {
  396.       msg(Window,"Both samples are not stereo.");
  397.       return(0);
  398.       }
  399.  
  400.    msg(Window,"Working...");
  401.  
  402.    len=samp->length[to]+end-start;
  403.  
  404.    if ((x=AllocMem(len,0))==0) {
  405.       nomem(Window);
  406.       return(0);
  407.       }
  408.  
  409.    if (samp->type[to]==STEREO)
  410.       if ((y=AllocMem(len,0))==0) {
  411.          nomem(Window);
  412.          FreeMem(x,len);
  413.          return(0);
  414.          }
  415.  
  416.    movmem(samp->lmem[to],x,position);
  417.    movmem(samp->lmem[from]+start,x+position,end-start);
  418.    movmem(samp->lmem[to]+position,x+position+end-start,
  419.           samp->length[to]-position);
  420.    FreeMem(samp->lmem[to],samp->length[to]);
  421.    samp->lmem[to]=x;
  422.  
  423.    if (samp->type[to]==STEREO) {
  424.       movmem(samp->rmem[to],y,position);
  425.       movmem(samp->rmem[from]+start,y+position,end-start);
  426.       movmem(samp->rmem[to]+position,y+position+end-start,
  427.           samp->length[to]-position);
  428.       FreeMem(samp->rmem[to],samp->length[to]);
  429.       samp->rmem[to]=y;
  430.       }
  431.     else samp->rmem[to]=x;
  432.  
  433.    samp->length[to]=len;
  434.    msg(Window,"");
  435.    }
  436.  
  437.  
  438. /***************************/
  439. /** Open a screen         **/
  440. /***************************/
  441.  
  442. openscr(width,depth)
  443. SHORT width,depth;
  444. {
  445. struct NewScreen cust;
  446. struct Screen *screen;
  447. static struct TextAttr thefont= {
  448.  
  449.    "topaz.font",
  450.    TOPAZ_SIXTY,
  451.    FS_NORMAL,
  452.    FPF_ROMFONT,
  453.    };
  454.  
  455. cust.LeftEdge=0;
  456. cust.TopEdge=199;
  457. cust.Width=width;
  458. cust.Height=200;
  459. cust.Depth=depth;
  460. cust.DetailPen=2;
  461. cust.BlockPen=3;
  462. cust.ViewModes=0;
  463. if (width>320) cust.ViewModes=HIRES;
  464. cust.Type=CUSTOMSCREEN;
  465. cust.Font=&thefont;
  466. cust.DefaultTitle=" this is te";
  467. cust.Gadgets=0;
  468. cust.CustomBitMap=0;
  469.  
  470. screen=OpenScreen(&cust);
  471. return((int)screen);
  472. }
  473.  
  474.  
  475.  
  476. /********************************/
  477. /* Load a ilbm File from disk   */
  478. /********************************/
  479.  
  480. load_ilbm (fname,iff,cmap)
  481.  
  482. struct Image *iff;
  483. char *fname;
  484. UBYTE *cmap;
  485.  
  486. {
  487. ULONG x;
  488. UBYTE planes;
  489. int plen,rowlen,len;
  490. int templen;
  491. register int i,z;
  492. int offset,in,k;
  493. BYTE *comp;
  494. static int p_tab[]={1,3,7,15,31,63};
  495.  
  496. iff->LeftEdge=0;
  497. iff->TopEdge=0;
  498. iff->NextImage=0;
  499. iff->PlaneOnOff=0;
  500.  
  501. if ((in=(int)open(fname,O_RDONLY))==-1)
  502.    return(-1);
  503.  
  504. read(in,&k,4);
  505.  
  506. if (k!=FORM) return (-1);
  507.  
  508. read(in,&x,4);    /* skip length */
  509. read(in,&x,4);    /* get form type */
  510. if (x!=ILBM) {
  511.    close(in);
  512.    return(-1);
  513.    }
  514.  
  515. nextchunk:
  516.  
  517. read(in,&x,4);     /* get chunk type */
  518. while (x!=BODY && x!=CMAP && x!=BMHD) {    /* skip if not what we want */
  519.    skip(in);
  520.    read(in,&x,4);
  521.    if (x==-1 || x==0) {
  522.       close(in);
  523.       return(-1);
  524.       }
  525.    }
  526.  
  527. if (x==CMAP) {
  528.    read(in,&len,4);
  529.    read(in,cmap,len);
  530.    if ((len&1)==1) lseek(in,1L,1);  /* skip padding bytes */
  531.    goto nextchunk;
  532.    }
  533.    
  534. if (x==BMHD) {
  535.    lseek(in,4L,1);   /* skip length */
  536.    read(in,&iff->Width,2);
  537.    read(in,&iff->Height,2);
  538.    lseek(in,4L,1);
  539.    read(in,&planes,1);
  540.    iff->Depth=(SHORT)planes;
  541.    iff->PlanePick=p_tab[planes];
  542.    lseek(in,11L,1);
  543.    goto nextchunk;
  544.    }
  545.  
  546. if (x==BODY) {
  547.    read(in,&templen,4);
  548.    comp=AllocMem(templen,0);
  549.    if (comp==0) {
  550.       printf("ERROR! not enough memory to load iff file!\n");
  551.       exit(0);
  552.       }
  553.    read(in,comp,templen);
  554.  
  555.    rowlen=iff->Width/8;
  556.    if (rowlen*8!=iff->Width) rowlen++;
  557.    plen=rowlen*iff->Height;
  558.    iff->ImageData=AllocMem(plen*iff->Depth,MEMF_CHIP);   /* change this? */
  559.    if (iff->ImageData==0) {
  560.       printf("ERROR! Out of memory\n");
  561.       exit(10);
  562.       }
  563.    offset=0;
  564.    for (i=0;i<iff->Height;i++)
  565.       for(k=0;k<iff->Depth;k++) {
  566.          z=uncomp(&offset,comp+offset,(BYTE *)iff->ImageData+rowlen*i+k*plen,rowlen);
  567.          if (z!=0) {
  568.             printf("ERROR! compression fault.\n");
  569.             exit(20);
  570.             }
  571.          }
  572.  
  573.    FreeMem(comp,templen);
  574.    close (in);
  575.    return(0);
  576.    }
  577. printf("ERROR: How did i get here?\n\n");
  578. }
  579.  
  580. /*********************************************************************/
  581. /*       Uncompress one row                                          */
  582. /* Control Bytes:                                                    */
  583. /*    [0..127]   : followed by n+1 bytes of data.                      */
  584. /*    [-1..-127] : followed by byte to be repeated (-n)+1 times.       */
  585. /*    -128       : NOOP.                                               */
  586. /*********************************************************************/
  587.  
  588. uncomp(offset,src,dest,width)
  589.  
  590. register char *src,*dest;
  591. int *offset,width;
  592. {
  593. register char n,val;
  594.  
  595.  
  596. while (width>0) {
  597.    if ((n=*src)>0) {
  598.    src++;
  599.    (*offset)++;
  600.    
  601.       while (n-->=0) {
  602.          *dest=*src;
  603.          dest++; src++; (*offset)++; width--;
  604.          }
  605.       }
  606.    else {
  607.       src++;
  608.       (*offset)++;
  609.       val=*src;
  610.       src++;
  611.       (*offset)++;
  612.       while (n++<=0) {
  613.          *dest=val; width--;
  614.          dest++;
  615.          }
  616.       }     /* end else */
  617.    }        /* end 1st while */
  618.  
  619. return (width);
  620. }
  621. /***********************************/
  622. /***        record a sample      ***/
  623. /***********************************/
  624.  
  625. digitze (Window,lp,rp,rate,maxnum,chan)
  626. char *rp,*lp;
  627. int rate,maxnum,chan;
  628. struct Window *Window;
  629. {
  630. register char *reg1,*reg2;
  631. register ULONG k;
  632. static int i;
  633. static UBYTE *data,*direction,*pa,*direction2,*data2;
  634.  
  635. direction=(UBYTE *)0xBFE301;     /* set bits here to a 1 for output */
  636. data=(UBYTE *)0xBFE101;
  637. pa=(UBYTE *)0xBFE001;
  638. data2=(UBYTE *)0xBFD000;
  639. direction2=(UBYTE *)0xBFD200;
  640.  
  641. reg1=lp;
  642. reg2=rp;
  643. *direction=0;           /* all bits are read */
  644. *data=0;
  645. *direction2=6;  /* pa1 and pa2 write */
  646. *data2=chan;
  647.  
  648. msg(Window,"RECORDING... Press the left mouse button to stop.");
  649. if ((*pa&64)==0) while((*pa&64)==0) ;
  650. for (k=0;k<20;k++) ;    /* skip key bbbounce */
  651. Disable();
  652. k=0;
  653. if (chan!=STEREO)
  654.    while (k++<maxnum && (*pa&64)==64) {
  655.       for(i=0;i<rate;i++);   /* delay loop */
  656.       *reg1++=(*data)-128;
  657.       }
  658. else {
  659.    rate=rate/2;
  660.    while (k++<maxnum && (*pa&64)==64) {
  661.       for(i=0;i<rate;i++);    /* delay loop */
  662.       *data2=RIGHT;
  663.       *reg2++=(*data)-128;
  664.       *data2=LEFT;
  665.       *reg1++=(*data)-128;
  666.       }
  667.    }
  668.  
  669. Enable();
  670. return((int)(k-1));
  671. }
  672.  
  673. /*********************************************/
  674. /***        listen to digitizer            ***/
  675. /*********************************************/
  676.  
  677. listen (chan)
  678. int chan;
  679. {
  680. static UBYTE *base,*pa,*data,*direction,*data2,*direction2;
  681. static unsigned short sam,i;
  682. unsigned short *aud0lch,*aud0len,*aud0vol,*aud0per,*aud0dat,*dmaconw;
  683. unsigned short *aud1lch,*aud1len,*aud1vol,*aud1per,*aud1dat;
  684. unsigned short *intreq,*intreqr;
  685. unsigned int *aud0lc,*aud1lc;
  686. direction=(UBYTE *)0xBFE301;     /* set bits here to a 1 for output */
  687. data=(UBYTE *)0xBFE101;
  688. data2=(UBYTE *)0xBFD000;
  689. direction2=(UBYTE *)0xBFD200;
  690.  
  691. *direction=0;           /* all bits are read */
  692. *data=0;
  693. *direction2=2+4;      /* pa1 & pa2 write */
  694. Disable();
  695.  
  696. base=(UBYTE *)0xDEF000;
  697. /* channel 0 chip addresses */
  698. dmaconw=(unsigned short *)(base+0x096);
  699. aud0lch=(unsigned short *)(base+0x0A0);
  700. aud0len=(unsigned short *)(base+0x0A4);
  701. aud0vol=(unsigned short *)(base+0x0A8);
  702. aud0per=(unsigned short *)(base+0x0A6);
  703. aud0dat=(unsigned short *)(base+0x0AA);
  704. aud0lc=(int *)aud0lch;
  705. /* channel 1 chip addresses */
  706. aud1lch=(unsigned short *)(base+0x0B0);
  707. aud1len=(unsigned short *)(base+0x0B4);
  708. aud1vol=(unsigned short *)(base+0x0B8);
  709. aud1per=(unsigned short *)(base+0x0B6);
  710. aud1dat=(unsigned short *)(base+0x0BA);
  711. aud1lc=(int *)aud1lch;
  712. intreq=(unsigned short *)(base+0x09C);
  713. intreqr=(unsigned short *)(base+0x1E);
  714. pa=(UBYTE *)0xBFE001;
  715.  
  716. *aud0vol=64;
  717. *aud0per=1;
  718. *aud1vol=64;
  719. *aud1per=1;
  720. i=0;
  721.  
  722. if (chan==STEREO)
  723.    while ((*pa&64)==64) {
  724.       *data2=LEFT;
  725.       sam=(*data-128);
  726.       sam=sam&0xFF;
  727.       i=sam|(sam<<8);
  728.       *aud0dat=i;
  729.       *intreq=128;    /* not in manual, but required to resart ch 0 */
  730.  
  731.       *data2=RIGHT;
  732.       sam=(*data-128);
  733.       sam=sam&0xFF;
  734.       i=sam|(sam<<8);
  735.       *aud1dat=i;
  736.       *intreq=256;    /* needed to restart ch 1 */
  737.       }
  738. *data2=chan;
  739. if (chan==RIGHT)
  740.    while ((*pa&64)==64) {
  741.       sam=(*data-128);
  742.       sam=sam&0xFF;
  743.       i=sam|(sam<<8);
  744.       *aud1dat=i;
  745.       *intreq=256;
  746.       }
  747.  
  748. if (chan==LEFT)
  749.    while ((*pa&64)==64) {
  750.       sam=(*data-128);
  751.       sam=sam&0xFF;
  752.       i=sam|(sam<<8);
  753.       *aud0dat=i;
  754.       *intreq=128;
  755.       }
  756. while ((*pa&64)!=64) ;     /* wait for left mouse button release */
  757. Enable();
  758. }
  759.  
  760. /********************************/
  761. /*** round up to nearest 8 byte**/
  762. /********************************/
  763.  
  764. rup(p)
  765.  
  766. char *p;
  767. {
  768. int i;
  769. i=(int)p;
  770. if ((i&0xFFFFFFF8)==i) return(i);
  771. return((i&0xFFFFFFF8)+8);
  772. }
  773.  
  774. rdn(i)
  775. int i;
  776. {
  777. return(i&0xFFFFFFF8);
  778. }
  779.  
  780. /************/
  781. /** alter  **/
  782. /************/
  783.  
  784. alter(val,maxval,x)
  785.  
  786. int maxval,x;
  787. int *val;
  788. {
  789. if (x>600 && x<621 && *val>0) *val=*val-1;
  790. if (x>621 && x<640 && *val<maxval) *val=*val+1;
  791. }
  792.  
  793. /***********/
  794. /** even  **/
  795. /***********/
  796.  
  797. even(i)
  798. int i;
  799. {
  800. return(0xFFFFFFFE&i);
  801. }
  802.  
  803. /**************************/
  804. /**  get a clicked slot  **/
  805. /**************************/
  806.  
  807. pickslot(Window,samp)
  808. struct Window *Window;
  809. struct Samp *samp;
  810. {
  811. struct IntuiMessage *message;
  812. int class,code,mousex,mousey;
  813.  
  814. zap:
  815. if((message=(struct IntuiMessage *)GetMsg(Window->UserPort))==0) {
  816.    Wait(1<<Window->UserPort->mp_SigBit);
  817.    goto zap;
  818.    }
  819. class=message->Class;
  820. code=message->Code;
  821. mousex=message->MouseX;
  822. mousey=message->MouseY;
  823. ReplyMsg(message);
  824.  
  825. if (class==MOUSEBUTTONS) {        /* selecting a new cur */
  826.    if (code!=SELECTDOWN) goto zap;
  827.    mousey=(mousey-11)/8;
  828.    if (mousex>320) mousey+=MAX_SAMPLES/2;
  829.    if (mousey>MAX_SAMPLES || samp->lmem[mousey]==0) {
  830.       msg(Window,"Invalid Selection, try again.");
  831.       goto zap;
  832.       }
  833.    }
  834. return(mousey);
  835. }
  836.  
  837. /**********************************/
  838. /**  write msg to cmd line       **/
  839. /**********************************/
  840. msg (Window,message)
  841. char *message;
  842. struct Window *Window;
  843. {
  844. int i;
  845.  
  846. putxy(Window,23,190,message,RED,BLACK);
  847. for (i=23+strlen(message)*8;i<630;i=i+8)
  848.    putxy(Window,i,190," ",BLACK,BLACK);
  849. }
  850.  
  851. /************************************/
  852. /**  Print   "out of memory" msg    */
  853. /************************************/
  854.  
  855. nomem(Window)
  856. struct Window *Window;
  857. {
  858. msg(Window,"OUT OF MEMORY");
  859. }
  860.  
  861. /******************************************/
  862. /**  allocate an audio channel          ***/
  863. /******************************************/
  864.  
  865. allocate_channel (Window,IOB)
  866. struct Window *Window;
  867. struct IOAudio *IOB;
  868. {
  869. struct MsgPort *port;
  870. int i;
  871. char *x;
  872. static UBYTE allocation_map[] = {3};
  873.  
  874. x=(char *)IOB;
  875. for (i=0;i<sizeof(struct IOAudio);i++)
  876.    x[i]=(char)0;
  877.  
  878. if (OpenDevice(AUDIONAME, 0, IOB, 0) != 0)
  879.    msg (Window,"can't open audio device");
  880.  
  881. /* now allocate a channel */
  882.  
  883. IOB->ioa_Request.io_Message.mn_Node.ln_Pri = SOUNDPREC;
  884. if ((port=(struct MsgPort *)CreatePort("samples", 0)) == 0)
  885.    msg (Window,"can't open port");
  886. IOB->ioa_Request.io_Message.mn_ReplyPort = port;
  887. IOB->ioa_Request.io_Command = ADCMD_ALLOCATE;
  888. IOB->ioa_Data = allocation_map;
  889. IOB->ioa_Length = sizeof (allocation_map);
  890.  
  891. SendIO (IOB);
  892. if (WaitIO (IOB))
  893.    msg (Window,"error in allocation");
  894.  
  895. }
  896.  
  897. /****************************************/
  898. /** deallocate an audio channel        **/
  899. /****************************************/
  900.  
  901. deallocate_channel (IOB)
  902. struct IOAudio *IOB;
  903. {
  904. struct Device *device;
  905. struct MsgPort *port;
  906.  
  907. if (IOB != 0) {
  908.    device = IOB->ioa_Request.io_Device;
  909.    if (device != 0) {
  910.       IOB->ioa_Request.io_Command = ADCMD_FREE;
  911.       DoIO (IOB);
  912.       CloseDevice (IOB);
  913.    }
  914.    port = IOB->ioa_Request.io_Message.mn_ReplyPort;
  915.    if (port != 0)
  916.       DeletePort (port);
  917. }
  918. }
  919.  
  920. /*************************************************/
  921. /**  Play a sample on an alocated channel       **/
  922. /*************************************************/
  923.  
  924. tochan (IOB, data, length, rate,cyc)
  925. int rate,length,cyc;
  926. char *data;
  927. struct IOAudio *IOB;
  928. {
  929.  
  930. IOB->ioa_Request.io_Command = CMD_WRITE;
  931.  
  932. IOB->ioa_Request.io_Flags = ADIOF_PERVOL;
  933.  
  934. IOB->ioa_Data = data;
  935. IOB->ioa_Length = (ULONG)length;
  936.  
  937. IOB->ioa_Period = rate;
  938. IOB->ioa_Volume = 64;
  939.  
  940. IOB->ioa_Cycles = cyc;
  941.  
  942. BeginIO (IOB);
  943. }
  944.  
  945. /*****************************************************/
  946. /* PutName -- put a sample name in the correct place */
  947. /*****************************************************/
  948.  
  949. PutName(Window,name,location,vid)
  950.  
  951. struct Window *Window;
  952. char *name;
  953. int location;
  954. int vid;
  955. {
  956. int x;
  957. if (location>=MAX_SAMPLES/2) {
  958.    x=320;
  959.    location=location-MAX_SAMPLES/2;
  960.    }
  961.    else x=3;
  962.  
  963. if (name[0]==0) {
  964.    for (vid=x;vid<x+305;vid=vid+8)
  965.       putxy(Window,vid,11+location*8," ",BLACK,BLACK);
  966.    return(0);
  967.    }
  968.  
  969. if (vid==REV_VID)
  970.    putxy(Window,x,11+location*8,name,BLACK,WHITE);
  971. else
  972.    putxy(Window,x,11+location*8,name,WHITE,BLACK);
  973. }
  974.  
  975.